home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / misc / coding / midas060 / src / dsmnsnd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-16  |  6.6 KB  |  334 lines

  1. /*      dsmnsnd.c
  2.  *
  3.  * Mixing No Sound Sound Device
  4.  *
  5.  * $Id: dsmnsnd.c,v 1.2 1997/01/16 18:41:59 pekangas Exp $
  6.  *
  7.  * Copyright 1996,1997 Housemarque Inc.
  8.  *
  9.  * This file is part of the MIDAS Sound System, and may only be
  10.  * used, modified and distributed under the terms of the MIDAS
  11.  * Sound System license, LICENSE.TXT. By continuing to use,
  12.  * modify or distribute this file you indicate that you have
  13.  * read the license and understand and accept it fully.
  14. */
  15.  
  16. /* None of these functions can fail and practically none of them does
  17.    anything. */
  18.  
  19. #include "lang.h"
  20.  
  21. #ifdef __WIN32__
  22. #define WIN32_LEAN_AND_MEAN
  23. #include "windows.h"
  24. #endif
  25.  
  26. #include "mtypes.h"
  27. #include "errors.h"
  28. #include "sdevice.h"
  29. #include "dsm.h"
  30.  
  31. RCSID(const char *dsmnsnd_rcsid = "$Id: dsmnsnd.c,v 1.2 1997/01/16 18:41:59 pekangas Exp $";)
  32.  
  33. #define MIXRATE 4000
  34. #define MIXMODE dsmMixMono
  35. #define OUTPUTMODE sd16bit | sdMono
  36. #define MAXTIME 500
  37. #define MINTIME 10
  38.  
  39.  
  40.     /* A lot of functions do not use their arguments: */
  41. //#ifdef __WATCOMC__
  42. //#pragma off (unreferenced)
  43. //#endif
  44.  
  45.  
  46.  
  47.  
  48. /* Names and stuff: */
  49. static char     *nsndCard = "No Sound";
  50.  
  51.  
  52. /* Variables: */
  53. static DWORD    prevPlayTime;
  54. static DWORD    playElemsLeft;
  55. static unsigned nsndMasterVolume;
  56. static unsigned updateMix;              /* number of elements to mix between
  57.                                            two updates */
  58. static unsigned mixLeft;                /* number of elements to mix before
  59.                                            next update */
  60.  
  61.  
  62. /* Local prototypes: */
  63. int CALLING nsndSetUpdRate(unsigned updRate);
  64.  
  65.  
  66. enum nsndFunctIDs
  67. {
  68.     ID_nsndDetect = ID_nsnd,
  69.     ID_nsndInit,
  70.     ID_nsndClose,
  71.     ID_nsndGetMixRate,
  72.     ID_nsndGetMode,
  73.     ID_nsndOpenChans,
  74.     ID_nsndCloseChans,
  75.     ID_nsndClearChans,
  76.     ID_nsndMute,
  77.     ID_nsndPause,
  78.     ID_nsndSetMaster,
  79.     ID_nsndPlaySound,
  80.     ID_nsndStopSound,
  81.     ID_nsndSetRate,
  82.     ID_nsndGetRate,
  83.     ID_nsndSetVol,
  84.     ID_nsndSetInst,
  85.     ID_nsndSetPos,
  86.     ID_nsndGetPos,
  87.     ID_nsndSetPanning,
  88.     ID_nsndGetPanning,
  89.     ID_nsndMuteChannel,
  90.     ID_nsndAddInst,
  91.     ID_nsndRemInst,
  92.     ID_nsndSetUpdRate,
  93.     ID_nsndPlay,
  94.     ID_nsndGetMasterVolume,
  95.     ID_nsndGetVolume,
  96.     ID_nsndGetInstrument,
  97.     ID_nsndStartPlay,
  98.     ID_nsndSetAmplification,
  99.     ID_nsndGetAmplification
  100. };
  101.  
  102.  
  103.  
  104.  
  105. static int CALLING nsndDetect(int *result)
  106. {
  107.     /* No Sound is always there */
  108.     *result = 1;
  109.     return OK;
  110. }
  111.  
  112.  
  113. static int CALLING nsndInit(unsigned mixRate, unsigned mode)
  114. {
  115.     int         error;
  116.  
  117.     /* Initialize DSM - we'll be mixing the data: */
  118.     if ( (error = dsmInit(MIXRATE, MIXMODE, 16)) != OK )
  119.         PASSERROR(ID_nsndInit);
  120.  
  121.     /* Set update rate to 50Hz: */
  122.     if ( (error = nsndSetUpdRate(5000)) != OK )
  123.         PASSERROR(ID_nsndInit);
  124.  
  125.     /* Set real DSM master volume to 0 to speed up mixing: */
  126.     if ( (error = dsmSetMasterVolume(0)) != OK )
  127.         PASSERROR(ID_nsndInit);
  128.  
  129.     /* Initialize "previous" playing tick count: */
  130. #ifdef __WIN32__
  131.     prevPlayTime = GetTickCount();
  132. #endif
  133.  
  134.     return OK;
  135. }
  136.  
  137.  
  138. static int CALLING nsndClose(void)
  139. {
  140.     int         error;
  141.  
  142.     /* Just uninitialize DSM: */
  143.     if ( (error = dsmClose()) != OK )
  144.         PASSERROR(ID_nsndClose);
  145.  
  146.     return OK;
  147. }
  148.  
  149.  
  150. int CALLING nsndGetMode(unsigned *mode)
  151. {
  152.     /* Return our default mode: */
  153.     *mode = OUTPUTMODE;
  154.     return OK;
  155. }
  156.  
  157.  
  158. int CALLING nsndSetMasterVolume(unsigned masterVolume)
  159. {
  160.     /* Just store the master volume, don't set it to DSM: */
  161.     nsndMasterVolume = masterVolume;
  162.  
  163.     return OK;
  164. }
  165.  
  166.  
  167. int CALLING nsndGetMasterVolume(unsigned *masterVolume)
  168. {
  169.     /* Return our stored master vol: */
  170.     *masterVolume = nsndMasterVolume;
  171.  
  172.     return OK;
  173. }
  174.  
  175.  
  176. int CALLING nsndSetUpdRate(unsigned updRate)
  177. {
  178.     /* Calculate number of elements to mix between two updates: (even) */
  179.     mixLeft = updateMix = ((unsigned) ((100L * (ulong) MIXRATE) /
  180.         ((ulong) updRate)) + 1) & 0xFFFFFFFE;
  181.  
  182.     return OK;
  183. }
  184.  
  185.  
  186. int CALLING nsndStartPlay(void)
  187. {
  188.     DWORD       time, timeDiff;;
  189.  
  190.     /* Get the time in milliseconds since last nsndStartPlay(): */
  191. #ifdef __WIN32__
  192.     time = GetTickCount();
  193. #endif
  194.     timeDiff = time - prevPlayTime;
  195.     prevPlayTime = time;
  196.  
  197.     /* Restrict the time difference to reasonable values: */
  198.     if ( timeDiff > MAXTIME )
  199.         timeDiff = MAXTIME;
  200.     if ( timeDiff < MINTIME )
  201.         timeDiff = 0;
  202.  
  203.     /* Calculate the number of elements that fits into this time - it is the
  204.        amount we'll mix this polling time: */
  205.     playElemsLeft = (timeDiff * MIXRATE) / 1000;
  206.  
  207.     return OK;
  208. }
  209.  
  210.  
  211. int CALLING nsndPlay(int *callMP)
  212. {
  213.     int         error;
  214.     unsigned    dsmBufSize;
  215.     unsigned    numElems, doNow;
  216.  
  217.     if ( !playElemsLeft )
  218.     {
  219.         *callMP = 0;
  220.         return OK;
  221.     }
  222.  
  223. #ifdef __32__
  224.     dsmBufSize = dsmMixBufferSize >> 2;
  225. #else
  226.     dsmBufSize = dsmMixBufferSize >> 1;
  227. #endif
  228. #if MIXMODE == dsmMixStereo
  229.     dsmBufSize >>= 1;
  230. #endif
  231.  
  232.     if ( playElemsLeft > mixLeft )
  233.         numElems = mixLeft;
  234.     else
  235.         numElems = playElemsLeft;
  236.     mixLeft -= numElems;
  237.     playElemsLeft -= numElems;
  238.  
  239.     while ( numElems )
  240.     {
  241.         if ( numElems > dsmBufSize )
  242.             doNow = dsmBufSize;
  243.         else
  244.             doNow = numElems;
  245.         numElems -= doNow;
  246.  
  247.         if ( (error = dsmMixData(doNow)) != OK )
  248.             PASSERROR(ID_nsndPlay)
  249.     }
  250.  
  251.     /* Check if the music player should be called: */
  252.     if ( mixLeft == 0 )
  253.     {
  254.         mixLeft = updateMix;
  255.         *callMP = 1;
  256.     }
  257.     else
  258.     {
  259.         *callMP = 0;
  260.     }
  261.  
  262.     return OK;
  263. }
  264.  
  265.  
  266. /* And the struct: */
  267.  
  268. SoundDevice MixNoSound = {
  269.     0,                                  /* Poll to tempo */
  270.     sdUseDSM,
  271.     0,
  272.     0,
  273.     0,
  274.     1,
  275.     1,
  276.     sdMono | sd16bit,
  277.     "Mixing No Sound Sound Device",
  278.     &nsndCard,
  279.     0,
  280.     NULL,
  281.     &nsndDetect,
  282.     &nsndInit,
  283.     &nsndClose,
  284.     &dsmGetMixRate,
  285.     &nsndGetMode,
  286.     &dsmOpenChannels,
  287.     &dsmCloseChannels,
  288.     &dsmClearChannels,
  289.     &dsmMute,
  290.     &dsmPause,
  291.     &dsmSetMasterVolume,
  292.     &dsmGetMasterVolume,
  293.     &dsmSetAmplification,
  294.     &dsmGetAmplification,
  295.     &dsmPlaySound,
  296.     &dsmReleaseSound,
  297.     &dsmStopSound,
  298.     &dsmSetRate,
  299.     &dsmGetRate,
  300.     &dsmSetVolume,
  301.     &dsmGetVolume,
  302.     &dsmSetSample,
  303.     &dsmGetSample,
  304.     &dsmSetPosition,
  305.     &dsmGetPosition,
  306.     &dsmGetDirection,
  307.     &dsmSetPanning,
  308.     &dsmGetPanning,
  309.     &dsmMuteChannel,
  310.     &dsmAddSample,
  311.     &dsmRemoveSample,
  312.     &nsndSetUpdRate,
  313.     &nsndStartPlay,
  314.     &nsndPlay
  315. #ifdef SUPPORTSTREAMS
  316.     ,
  317.     &dsmStartStream,
  318.     &dsmStopStream
  319. #endif
  320. };
  321.  
  322.  
  323. /*
  324.  * $Log: dsmnsnd.c,v $
  325.  * Revision 1.2  1997/01/16 18:41:59  pekangas
  326.  * Changed copyright messages to Housemarque
  327.  *
  328.  * Revision 1.1  1996/07/29 19:35:39  pekangas
  329.  * Initial revision
  330.  *
  331.  * Revision 1.1  1996/05/22 20:49:33  pekangas
  332.  * Initial revision
  333.  *
  334. */